//
// Created by 覃州 on 2024/1/18.
//

#ifndef CRCANON_FUNCTION_EXECUTE_COUNT_H
#define CRCANON_FUNCTION_EXECUTE_COUNT_H

#include <cstdint>
#include "log/log.h"
#include "component/atomic_map.h"

namespace Canon {

class FunctionReflection
{
public:
    static FunctionReflection* GetInstance()
    {
        static FunctionReflection funcReflection;
        return &funcReflection;
    }

    auto GetCount(const std::string& funcName)
    {
        assert(funcExecCnt[funcName] < UINT16_MAX);
        return ++funcExecCnt[funcName];
    }

private:
    FunctionReflection() = default;

private:
    Component::AtomicMap<std::string, uint16_t> funcExecCnt;
};

class FunctionExecCnt
{
public:
    void Before()
    {
        LOG_WARN("[FunctionExecCnt] Start execute function %s", m_type.c_str());
    }

    void After()
    {
        LOG_WARN("[FunctionExecCnt] Function %s executed %d times",
                 m_type.c_str(),
                 FunctionReflection::GetInstance()->GetCount(m_type));
    }

    void SetType(const std::string& type) { m_type = "[" + type + "]"; }

private:
    std::string m_type;
};

} // namespace Canon

#endif // CRCANON_FUNCTION_EXECUTE_COUNT_H
